using System;
using System.Collections.Generic;
using System.Text;
using ESBSimpleSamples.ServiceClient.Interfaces;
using esb= Microsoft.Practices.ESB;
using ESBSimpleSamples.ServiceClient.Itineraries;
using ESBSimpleSamples.ServiceClient.Helpers;
using System.Xml;
using ESBSimpleSamples.ServiceClient.ServiceBrokers;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace ESBSimpleSamples.ServiceClient.ServiceRequests
{
    public abstract class ESBServiceRequest<TRequest, TResponse> : IServiceRequest<ItineraryRequest, XmlNode>
        where TRequest : class, new() 
        where TResponse : class, new()
    {
        public abstract ItineraryRequest PrepareRequest();
        
        private Dictionary<string, object> _parameters;

        private TRequest _request;
        private TResponse _response;

        public TRequest Request
        {
            get 
            {
                if (this._request == null)
                {
                    this._request = new TRequest();
                }
                return this._request; 
            }
            set { this._request = value; }
        }

        public TResponse Response
        {
            get 
            {
                if (this._response == null)
                {
                    this._response = this.GetResponse();
                }
                return this._response; 
            }
            set { this._response = value; }
        }

        protected Dictionary<string, object> Parameters
        {
            get 
            {
                if (this._parameters == null)
                {
                    this._parameters = new Dictionary<string, object>();
                }
                return this._parameters;
            }
        }

        protected virtual XmlNode GetRequestBody()
        {
            return SerializationHelper.Serialize(this._request);
        }

        public virtual void PrepareResponse(XmlNode response)
        {
            this._response = SerializationHelper.ChangeType<TResponse>(response);
        }

        protected TResponse GetResponse()
        {
            ItineraryRequest request = this.PrepareRequest();
            ESBServiceBroker broker = new ESBServiceBroker();
            XmlNode response = broker.SubmitRequestResponse(request);
            this.PrepareResponse(response);
            return this.Response;
        }
    }
}
